package org.lee.pattern.strategy;

import lombok.SneakyThrows;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * BeanContainer
 * bean容器，模拟spring
 * 仅模拟单线程下
 *
 * @author dralee
 * @date 2022-03-09 10:55:41
 **/
public class BeanContainer {
    private final Map<Class, Map<String, Object>> BEANS = new HashMap<>();

    @SneakyThrows
    private <T> T newInstance(Class clazz) {
        return (T) clazz.newInstance();
    }

    public void register(Class clazz, String name) {
        if (BEANS.containsKey(clazz)) {
            if (Objects.isNull(name) || name.isEmpty()) {
                return;
            }
            Map<String, Object> values = BEANS.get(clazz);
            if (values.containsKey(name)) {
                return;
            }
            Object obj = newInstance(clazz);
            if (obj == null) {
                throw new RuntimeException(clazz.getTypeName() + " instance failure.");
            }
            values.put(name, obj);
            return;
        }
        Map<String, Object> vals = new HashMap<>();
        Object obj = newInstance(clazz);
        if (obj == null) {
            throw new RuntimeException(clazz.getTypeName() + " instance failure.");
        }
        vals.put(name, obj); // 默认null：xxx
        BEANS.put(clazz, vals);
    }

    public <T> T get(Class<T> clazz, String name) {
        if (!BEANS.containsKey(clazz)) {
            return null;
        }
        return (T) ((Map<String, Object>) BEANS.get(clazz)).get(name);
    }

    public <T> T get(Class<T> clazz) {
        return get(clazz, null);
    }

    private BeanContainer() {
    }

    public static BeanContainer getContainer() {
        return BeanContainerInner.instance;
    }

    public static final class BeanContainerInner {
        private final static BeanContainer instance = new BeanContainer();
    }
}
